package com.nc.delivery_project.client.orders;

import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;
import com.nc.delivery_project.client.order_details.OrderDetailsPlace;
import com.nc.delivery_project.shared.proxy.OrderProxy;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Natalie D.
 * Date: 1/17/15
 * Time: 9:19 PM
 */
public class OrdersView extends Composite {
    interface OrderViewUiBinder extends UiBinder<VerticalPanel, OrdersView> {
    }

    private static OrderViewUiBinder uiBinder = GWT.create(OrderViewUiBinder.class);

    private ListDataProvider<OrderProxy> dataProvider;

    private List<OrderProxy> dataList;

    ColumnSortEvent.ListHandler<OrderProxy> sortHandler;

    @UiField
    VerticalPanel panel;

    @UiField
    TextBox filterTxtBox;

    @UiField
    DataGrid<OrderProxy> ordersDataGrid;

    @UiField
    SimplePager pager;

    @UiField
    Button addBtn;

    private OrdersPresenter presenter;

    public OrdersView() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    public void setPresenter(OrdersPresenter presenter) {
        this.presenter = presenter;
    }

    public void start() {
        panel.setCellWidth(ordersDataGrid, "100%");
        panel.setCellWidth(pager, "100%");

        ordersDataGrid.setWidth("100%");
        ordersDataGrid.setHeight("400px");
        ordersDataGrid.setEmptyTableWidget(new HTML("No Data to Display"));

        pager.setDisplay(ordersDataGrid);

        dataProvider = new ListDataProvider<>();
        dataProvider.setList(new ArrayList<OrderProxy>());

        sortHandler = new ColumnSortEvent.ListHandler<>(dataProvider.getList());

        initTableColumns(ordersDataGrid, sortHandler);

        ordersDataGrid.addColumnSortHandler(sortHandler);

        dataProvider.addDataDisplay(ordersDataGrid);

        filterTxtBox.addKeyUpHandler(new KeyUpHandler() {
            @Override
            public void onKeyUp(KeyUpEvent event) {
                filter(filterTxtBox.getText());
            }
        });

        addBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
              //  presenter.goTo(new AddOrderPlace(""));
            }
        });
    }

    private void filter(String filteredName) {
        List<OrderProxy> filteredOrders = new ArrayList<>();
        for (OrderProxy order : dataList) {
            if (String.valueOf(order.getId()).contains(filteredName)) {
                filteredOrders.add(order);
            }
        }

        bindData(filteredOrders);
    }

    public void initTableColumns(DataGrid<OrderProxy> dataGrid, ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> idCol = createIdCol(sortHandler);
        Column<OrderProxy, String> senderCol = createSenderCol(sortHandler);
        Column<OrderProxy, String> receiverCol = createReceiverCol(sortHandler);
        Column<OrderProxy, String> startDateCol = createStartDateCol(sortHandler);
        Column<OrderProxy, String> deliveryDateCol = createDeliveryDateCol(sortHandler);
        Column<OrderProxy, String> commentCol = createCommentCol(sortHandler);
        Column<OrderProxy, String> statusCol = createStatusCol(sortHandler);
        Column<OrderProxy, String> paymentCol = createPaymentCol(sortHandler);

        Column<OrderProxy, String> orderDetailsBtnCol = createDetailsBtnCol();

        dataGrid.addColumn(idCol, "ID");
        dataGrid.addColumn(senderCol, "Sender");
        dataGrid.addColumn(receiverCol, "Receiver");
        dataGrid.addColumn(startDateCol, "Start Date");
        dataGrid.addColumn(deliveryDateCol, "Delivery Date");
        dataGrid.addColumn(commentCol, "Comment");
        dataGrid.addColumn(statusCol, "Status");
        dataGrid.addColumn(paymentCol, "Payment");
        dataGrid.addColumn(orderDetailsBtnCol, "Details");
    }

    private Column<OrderProxy, String> createStartDateCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                if (object.getStartDate()!=null)
                return object.getStartDate();
                return "no date";
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getStartDate().compareToIgnoreCase(o2.getStartDate());
            }
        });
        return col;
    }
    private Column<OrderProxy, String> createDeliveryDateCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                if (object.getDeliveryDate()!=null)
                return object.getDeliveryDate();
                return "no date";
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getDeliveryDate().compareToIgnoreCase(o2.getDeliveryDate());
            }
        });
        return col;
    }
    private Column<OrderProxy, String> createCommentCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                return object.getComment();
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getComment().compareToIgnoreCase(o2.getComment());
            }
        });
        return col;
    }
    private Column<OrderProxy, String> createStatusCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                return object.getStatus();
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getStatus().compareToIgnoreCase(o2.getStatus());
            }
        });
        return col;
    }
    private Column<OrderProxy, String> createPaymentCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                if (object.getPayment()!=null)
                return String.valueOf(object.getPayment().getAmount());
                return "no payment set";
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return String.valueOf(o1.getPayment().getAmount()).compareToIgnoreCase(String.valueOf(o2.getPayment().getAmount()));
            }
        });
        return col;
    }

    private Column<OrderProxy, String> createSenderCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                return object.getSender().getEmail();
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getSender().getEmail().compareToIgnoreCase(o2.getSender().getEmail());
            }
        });
        return col;
    }

    private Column<OrderProxy, String> createReceiverCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler) {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell()) {
            @Override
            public String getValue(OrderProxy object) {
                return object.getReceiver().getEmail();
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                return o1.getReceiver().getEmail().compareToIgnoreCase(o2.getReceiver().getEmail());
            }
        });
        return col;
    }

    private Column<OrderProxy, String> createIdCol(ColumnSortEvent.ListHandler<OrderProxy> sortHandler)
    {
        Column<OrderProxy, String> col = new Column<OrderProxy, String>(new TextCell())
        {
            @Override
            public String getValue(OrderProxy object)
            {
                return String.valueOf(object.getId());
            }
        };

        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<OrderProxy>() {
            @Override
            public int compare(OrderProxy o1, OrderProxy o2) {
                if (o1.getId() == o2.getId()) {
                    return 0;
                } else {
                    return o1.getId() > o2.getId() ? 1 : -1;
                }
            }
        });
        return col;
    }

    private Column<OrderProxy, String> createDetailsBtnCol() {
        Column<OrderProxy, String> detailsBtnCol = new Column<OrderProxy, String>(new ButtonCell()) {
            @Override
            public String getValue(OrderProxy object) {
                return "->";
            }
        };
        detailsBtnCol.setFieldUpdater(new FieldUpdater<OrderProxy, String>() {
            @Override
            public void update(int index, OrderProxy object, String value) {
                presenter.goTo(new OrderDetailsPlace(String.valueOf(dataProvider.getList().get(index).getId())));
            }
        });
        return detailsBtnCol;
    }

    public void setDataList(List<OrderProxy> dataList) {
        this.dataList = dataList;
        bindData(dataList);
    }

    public void bindData(List<OrderProxy> orders) {
        dataProvider.setList(orders);
        sortHandler.setList(dataProvider.getList());
        dataProvider.refresh();
    }
}
